package org.mii.safeguard_v1.security.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.mii.safeguard_v1.base.service.ServiceException;
import org.mii.safeguard_v1.base.web.CrudActionSupport;
import org.mii.safeguard_v1.security.entity.Role;
import org.mii.safeguard_v1.security.entity.User;
import org.mii.safeguard_v1.security.service.IRoleManager;
import org.mii.safeguard_v1.security.service.IUserManager;
import org.mii.safeguard_v1.security.service.util.AuthorityUtils;
import org.mii.safeguard_v1.util.AjaxJQueryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.Md5PasswordEncoder;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.PropertyFilter;
import org.springside.modules.orm.hibernate.HibernateWebUtils;
import org.springside.modules.web.struts2.Struts2Utils;

/**
 * 用户管理Action.
 * 
 * 使用Struts2 convention-plugin annotation定义Action参数.
 * 
 * @author calvin
 */
@SuppressWarnings("serial")
@Results( {
		@Result(name = CrudActionSupport.RELOAD, location = "user.action", type = "redirect"),
		@Result(name = CrudActionSupport.NOTICE, location = "notice.jsp", type = "redirect"),
		@Result(name = CrudActionSupport.DENY_ACCESS, location = "common/403.jsp", type = "redirect") })
@Namespace("/security")
public class UserAction extends CrudActionSupport<User> {

	@Autowired
	private IUserManager userManager;
	@Autowired
	private IRoleManager roleManager;

	// 基本属性
	private User entity;
	private Integer id;
	private Page<User> page = new Page<User>(5);// 每页5条记录
	
	private String key;

	// 角色相关属性
	private List<Role> allRoles; // 全部可选角色列表
	private List<Integer> checkedRoleIds; // 页面中钩选的角色id列表

	private Map<String, Object> resultMap = new HashMap<String, Object>();

	// 基本属性访问函数 //

	public User getModel() {
		return entity;
	}

	
	

	@Override
	protected void prepareModel() throws Exception {
		if (id != null) {
			entity = userManager.get(id);
		} else {
			entity = new User();
		}
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Page<User> getPage() {
		return page;
	}
	
	public Map<String, Object> getResultMap() {
		return resultMap;
	}

	public String getKey() {
		return key;
	}
	
	public void setKey(String key) {
		this.key = key;
	}
	// CRUD Action 函数 //

	@Override
	public String list() throws Exception {
		HttpServletRequest request = Struts2Utils.getRequest();
		List<PropertyFilter> filters = HibernateWebUtils
				.buildPropertyFilters(request);

		setPageParamters(page, request);

		page = userManager.search(page, filters);

		// 分页结束后，如果采用EcTable展示的话，需要将该属性设置到界面上
		request.setAttribute(TOTAL_ROWS,
				Integer.valueOf((int) page.getTotalCount()));

		return SUCCESS;
	}

	@Override
	public String input() throws Exception {
		// allRoles = roleManager.getAll();
		// checkedRoleIds = entity.getRoleIds();
		return INPUT;
	}

	@Override
	public String save() throws Exception {
		HttpServletRequest request = Struts2Utils.getRequest();
		String changePassword = request.getParameter("changePassword").trim();

		if ("1".equalsIgnoreCase(changePassword)) {
			// 判断密码是否修改过，修改后需要进行加密 采用盐值加密 很爽很安全
			Md5PasswordEncoder encoder = new Md5PasswordEncoder();
			entity.setPassword(encoder.encodePassword(entity.getPassword(),
					entity.getLoginName()));// 只能用登录名作为盐值 否则无法登录，不信你试试
		}

		userManager.save(entity);
		addActionMessage("保存用户成功");
		return RELOAD;
	}

	@Override
	public String delete() throws Exception {
		try {
			userManager.delete(id);
			addActionMessage("删除用户成功");
		} catch (ServiceException e) {
			logger.error(e.getMessage(), e);
			addActionMessage(e.getMessage());
		}
		return RELOAD;
	}

	// 其他属性访问函数与Action函数 //

	public List<Role> getAllRoles() {
		return allRoles;
	}

	public List<Integer> getCheckedRoleIds() {
		return checkedRoleIds;
	}

	public void setCheckedRoleIds(List<Integer> checkedRoleIds) {
		this.checkedRoleIds = checkedRoleIds;
	}

	/**
	 * 支持使用Jquery.validate Ajax检验用户名是否重复.
	 */
	public String checkLoginName() {
		HttpServletRequest request = ServletActionContext.getRequest();
		String loginName = request.getParameter("loginName");
		String oldLoginName = request.getParameter("oldLoginName");

		if (userManager.isLoginNameUnique(loginName, oldLoginName)) {
			Struts2Utils.renderText("true");
		} else {
			Struts2Utils.renderText("false");
		}
		// 因为直接输出内容而不经过jsp,因此返回null.
		return null;
	}

	public String assignRole() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		allRoles = roleManager.getAll();
		entity = userManager.get(Integer.parseInt(request.getParameter("id")));
		AuthorityUtils.bindingAuthorizedResource(allRoles, entity.getRoleIds(),
				Role.class, "id", "isAuthorized");
		request.setAttribute("userId", entity.getId());
		request.setAttribute("userName", entity.getLoginName());

		return "authority";

	}

	public String changeAuth() throws Exception {
		HttpServletRequest request = Struts2Utils.getRequest();
		JSONObject jsonObject = AjaxJQueryUtils.readJson(request);
		String userId = jsonObject.getString("obId");
		String roleId = jsonObject.getString("opId");
		boolean ischecked = jsonObject.getInt("check") == 1;
		User entity = userManager.get(Integer.valueOf(userId));

		int udt = AuthorityUtils.updateAuthority(entity.getRoles(), Integer
				.valueOf(roleId), ischecked, "id", Role.class);
		// 重新保存
		userManager.save(entity);
		AjaxJQueryUtils.print(Struts2Utils.getResponse(), String.valueOf(udt));
		return null;
	}

	@Action(value = "/findPassword", results = { @Result(name = CrudActionSupport.SUCCESS, location = "findpassword.jsp", type = "redirect") })
	public String findPassword() {
		HttpServletRequest request = Struts2Utils.getRequest();
		String userName = request.getParameter("username");
		if (userName == null) {
			request.setAttribute("showForm", true);
		} else {
			
		}
		return SUCCESS;
	}
}
